﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Linq.Expressions;
using SL8.SL.Controls;
using System.Reflection;

namespace SL8.SL.Extensions
{
    public static class DependencyObjectExtension
    {
        /// <summary>
        /// 获取子元素扩展
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="element"></param>
        /// <returns></returns>
        public static List<T> GetChildElements<T>(this DependencyObject element)
            where T : class
        {
            List<T> list = new List<T>();
            DependencyObjectExtension.GetChildElements<T>(element, list, false);
            return list;
        }

        public static List<T> GetChildElements<T>(this DependencyObject element, bool inherit)
             where T : class
        {
            List<T> list = new List<T>();
            DependencyObjectExtension.GetChildElements<T>(element, list, inherit);
            return list;
        }

        public static List<T> GetChildElements<T>(DependencyObject element, List<T> list, bool inherit)
            where T : class
        {
            int count = VisualTreeHelper.GetChildrenCount(element);

            for (int i = 0; i < count; i++)
            {
                DependencyObject d = VisualTreeHelper.GetChild(element, i);

                if (d != null)
                {
                    if (inherit)
                    {
                        if (typeof(T).IsAssignableFrom(d.GetType()))
                        {
                            list.Add(d as T);
                        }
                    }
                    else
                    {
                        if (d.GetType() == typeof(T))
                        {
                            list.Add(d as T);
                        }
                    }

                    DependencyObjectExtension.GetChildElements<T>(d, list, inherit);
                }
            }

            return list;
        }

        public static T GetParent<T>(this DependencyObject element) where T : UIElement
        {
            DependencyObject parent = VisualTreeHelper.GetParent(element);

            while (parent != null)
            {
                if (parent.GetType() == typeof(T))
                {
                    return parent as T;
                }

                parent = VisualTreeHelper.GetParent(parent);
            }

            return null;
        }

        /// <summary>
        /// 验证所有子DataField
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public static bool ValidateChildDataFields(this DependencyObject element)
        {
            bool isValid = true;
            List<DataField> fields = element.GetChildElements<DataField>();

            foreach (DataField field in fields)
            {
                if (!field.Validate())
                {
                    isValid = false;
                }
            }

            return isValid;
        }

        public static LambdaExpression GetSearchExpression<T>(this DependencyObject element)
        {
            Type entityType = typeof(T);

            LambdaExpression returnLabda = null;
            var searchItems = element.GetChildElements<SearchItemBase>(true);

            foreach (var item in searchItems)
            {
                if (item.EntityType != null && item.EntityType == entityType)
                {
                    var expr = item.GetSearchExpression();

                    if (expr != null)
                    {
                        if (returnLabda == null)
                        {
                            returnLabda = expr;
                        }
                        else
                        {
                            returnLabda = System.Linq.Expressions.Expression.Lambda<Func<T, bool>>
                  (System.Linq.Expressions.Expression.AndAlso(returnLabda.Body, expr.Body), expr.Parameters);
                        }
                    }
                }
            }

            return returnLabda;
        }

        public static LambdaExpression GetSearchExpressionByEntityType(this DependencyObject element, Type entityType)
        {
            if (entityType == null || element == null)
            {
                return null;
            }

            MethodInfo methodInfo = typeof(DependencyObjectExtension).GetMethod("GetSearchExpression");
            MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(entityType);

            return genericMethodInfo.Invoke(null, new object[] { element }) as LambdaExpression;
        }

        #region 依赖扩展属性
        /// <summary>
        /// 扩展Object值
        /// </summary>
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached("Command",
            typeof(ICommand),
            typeof(DependencyObjectExtension),
            null);


        public static ICommand GetCommand(DependencyObject d)
        {
            return (ICommand)d.GetValue(DependencyObjectExtension.CommandProperty);
        }

        private static void SetCommand(DependencyObject d, object value)
        {
            d.SetValue(DependencyObjectExtension.CommandProperty, value);
        }
        #endregion
    }
}
